﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Algobox.JuicyLib.TimeSeries
{
    public class OHLCTimeSeries : List<OHLCTimesSeriesRecord>
    {
        /// <summary>
        /// Adds a record to the series in thread safe manner
        /// </summary>
        /// <param name="record"></param>
        public void AddTimeSeriesRecord(OHLCTimesSeriesRecord record)
        {
            this.Add(record);
        }

        /// <summary>
        /// Gets last record
        /// </summary>
        /// <returns>BaseTimeSeriesRecord</returns>
        public OHLCTimesSeriesRecord GetLastTimeSeriesRecord()
        {
            return GetLastTimeSeriesRecord(1);
        }
        /// <summary>
        /// Gets the Xth record from the back
        /// </summary>
        /// <param name="x"></param>
        /// <returns>BaseTimeSeriesRecord</returns>
        public OHLCTimesSeriesRecord GetLastTimeSeriesRecord(int x)
        {
            if (this.Count == 0 || this.Count < x)
                return null;
            else
                return this[this.Count - x];

        }

        /// <summary>
        /// shallow copy of data
        /// </summary>
        /// <param name="ts"></param>
        public void ShallowCopyBTS(OHLCTimeSeries ts)
        {
            ts.AddRange(this);
        }

        /// <summary>
        /// create new timeseries records
        /// </summary>
        /// <param name="ts"></param>
        public void DeepCopyBTS(OHLCTimeSeries ts)
        {
            for (int i = 0; i < this.Count; i++)
            {
                ts.Add(this[i].CreateNewCopy());
            }
        }


        public OHLCTimesSeriesRecord[] RemoveTicks(int ticks)
        {
            OHLCTimesSeriesRecord[] list = null;

            if (ticks <= 0)
                return list;

            if (ticks >= this.Count)
            {
                ticks = this.Count;
            }

            list = new OHLCTimesSeriesRecord[ticks];
            this.CopyTo(0, list, 0, ticks);

            this.RemoveRange(0, ticks);

            return list;
        }

        public OHLCTimesSeriesRecord[] RemoveTicks(DateTime now)
        {
            OHLCTimesSeriesRecord[] list = null;

            int counter = 0;
            for (int i = 0; i < this.Count; i++)
            {
                if (this[i] < now)
                {
                    counter++;
                }
                else
                    break;
            }

            if (counter > 0)
            {
                list = new OHLCTimesSeriesRecord[counter];
                this.CopyTo(0, list, 0, counter);
                this.RemoveRange(0, counter);
            }
            return list;
        }

        private DateTime timeFirst = DateTime.Now;
        /// <summary>
        /// Time is set on creation but can be overwritten by
        /// generator if required
        /// </summary>
        public DateTime TimeFirst
        {
            get { return timeFirst;  }
            set { timeFirst = value; }
        }


        private DateTime timeLast = DateTime.Now;
        /// <summary>
        /// Time is set on creation but can be overwritten by
        /// generator if required
        /// </summary>
        public DateTime TimeLast
        {
            get {  return timeLast; } 
            set {  timeLast = value; } 
        }

        
        /// <summary>
        /// Gets the last complete records from back of time series
        /// </summary>
        /// <param name="x"></param>
        /// <returns>Returns null if there is not enough records</returns>
        public OHLCTimeSeries GetLastCompleteRecords(int x)
        {
            lock (this)
            {
                if (this.Count < x + 1)
                    return null;
                else
                {
                    OHLCTimeSeries records = new OHLCTimeSeries();
                    
                    records.AddRange(this.GetRange(this.Count - x - 1, x));

                    return records;
                }
            }
        }
        

    }
}
